package member.order.action;

import m.common.action.ActionRequest;
import m.common.action.Param;
import m.common.action.RequestMethod;
import m.common.model.util.*;
import m.system.RuntimeData;
import m.system.db.DBManager;
import m.system.db.DataRow;
import m.system.exception.MException;
import m.system.util.*;
import member.base.model.UserInfo;
import member.base.service.BusinessInfoService;
import member.base.service.MemberInfoService;
import member.base.service.PageService;
import member.base.util.PowerUtil;
import member.order.model.OrderDetail;
import member.order.model.OrderInfo;
import member.order.model.OrderModel;
import member.order.model.OrderPay;
import member.order.service.RechargeOffsetService;
import member.order.util.MoneyRecordUtil;
import member.order.util.OrderCollectUtil;
import member.order.util.OrderNoUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@ActionRequest(name = "action/order/orderInfo",description = "订单信息")
public class OrderInfoAction extends OrderBaseAction<OrderInfo> {
    private OrderInfo model;
    private List<OrderDetail> list;
    private List<OrderPay> pays;

    @RequestMethod(description = "我的列表")
    public JSONMessage getMyList() throws Exception {
        ModelQueryList queryList=toQueryList(OrderInfo.class,"*","member.*","member.level.*");
        queryList.addCondition(QueryCondition.eq("business.oid", PowerUtil.getBusiness().getOid()));
        queryList.addCondition(QueryCondition.eq("inputUser.oid", PowerUtil.getUser().getOid()));
        setMemberPhoneNumExpression(queryList);
        return JSONMessage.success("查询成功").push("page", ModelQueryList.getModelPageInfo(queryList));
    }
    @RequestMethod(description = "审核列表")
    public JSONMessage getCheckList() throws Exception {
        PowerUtil.verifyPower(UserInfo.PowerStore);
        ModelQueryList queryList=toQueryList(OrderInfo.class,"*","member.*","member.level.*");
        queryList.addCondition(QueryCondition.eq("business.oid", PowerUtil.getBusiness().getOid()));
        queryList.addCondition(QueryCondition.eq("inputStore.oid", PowerUtil.getStore().getOid()));
        queryList.addCondition(QueryCondition.eq("status", OrderModel.StatusConfirm));
        setMemberPhoneNumExpression(queryList);
        return JSONMessage.success("查询成功").push("page", ModelQueryList.getModelPageInfo(queryList));
    }
    @RequestMethod(description = "店铺列表")
    public JSONMessage getStoreList() throws Exception {
        PowerUtil.verifyPower(UserInfo.PowerStore);
        ModelQueryList queryList=toQueryList(OrderInfo.class,"*","member.*","member.level.*");
        queryList.addCondition(QueryCondition.eq("business.oid", PowerUtil.getBusiness().getOid()));
        queryList.addCondition(QueryCondition.eq("inputStore.oid", PowerUtil.getStore().getOid()));
        queryList.addCondition(QueryCondition.eq("status", OrderModel.StatusDone));
        setMemberPhoneNumExpression(queryList);
        return JSONMessage.success("查询成功").push("page", ModelQueryList.getModelPageInfo(queryList));
    }
    @RequestMethod(description = "商家列表")
    public JSONMessage getBusinessList() throws Exception {
        PowerUtil.verifyPower(UserInfo.PowerManage);
        ModelQueryList queryList=toQueryList(OrderInfo.class,"*","member.*","member.level.*");
        queryList.addCondition(QueryCondition.eq("business.oid", PowerUtil.getBusiness().getOid()));
        setMemberPhoneNumExpression(queryList);
        return JSONMessage.success("查询成功").push("page", ModelQueryList.getModelPageInfo(queryList));
    }
    @RequestMethod(description = "获取信息")
    public JSONMessage getInfo(@Param("oid") String oid) throws Exception {
        OrderInfo model;
        if(StringUtil.isSpace(oid)){
            model=new OrderInfo();
            fillInitProperty(model);
            model.setAccountDate(new Date());
            model.setPayType(new String[]{OrderInfo.PayTypeBalance});
            model.setOrderAmount(0.0);
            model.setOtherAmount(0.0);
            list=new ArrayList<>();
            pays=new ArrayList<>();
        }else{
            ModelQueryList queryList=ModelQueryList.instance(OrderInfo.class,
                new String[]{"*","member.*","member.level.*",
                    "inputUser.realName","inputUser.phoneNum","serveUser.realName","serveUser.phoneNum","confirmUser.realName","confirmUser.phoneNum"},
                null,QueryCondition.eq("oid",oid)
            );
            setMemberPhoneNumExpression(queryList);
            model=queryList.getModel();
            list=ModelQueryList.getModelList(OrderDetail.class,new String[]{"*","serve.*","serve.type.*"},null,
                QueryCondition.eq("order.oid",oid),QueryOrder.asc("oid"));
            pays=ModelQueryList.getModelList(OrderPay.class,new String[]{"*"},null,
                QueryCondition.eq("order.oid",oid),QueryOrder.asc("oid"));
        }
        PowerUtil.verifyBusiness(model.getBusiness());
        return JSONMessage.success("查询成功")
            .push("model",model)
            .push("list",list)
            .push("pays",pays)
            .push("dayRate",getService(BusinessInfoService.class).getDiscount(model.getInputDate()))
            .push("editable", OrderInfo.StatusSave.equals(model.getStatus())
                &&PowerUtil.hasPower(model.getInputUser()))
            .push("confirmable",OrderInfo.StatusConfirm.equals(model.getStatus())
                &&PowerUtil.hasPower(UserInfo.PowerStore)
                &&PowerUtil.hasPower(model.getInputStore()));
    }

    @Override
    public OrderInfo saveOrder() throws Exception {
        model.setBusiness(PowerUtil.verifyBusiness(model.getBusiness()));
        ModelQueryCheck.init(model)
            .checkNotNull("member.oid","请选择会员")
            .checkNotNull("serveUser.oid","请选择服务员工")
            .checkNotNull("otherAmount","请输入其他金额")
            .checkNotNull("accountDate","请选择账期")
            .doCheck(false,true);
        if(null==pays||pays.isEmpty()) throw new MException("请选择付款方式");
        model.setMember(getService(MemberInfoService.class).get(model.getMember().getOid()));
        if(ObjectUtil.notEmptyOid(model)){
            ModelCheckUtil.equals(model,new String[]{"status","inputUser.oid"},new Object[]{OrderModel.StatusSave,PowerUtil.getUser().getOid()},"状态错误");
        }else{
            fillInitProperty(model);
            model.setOrderNo(OrderNoUtil.newOrderNo(OrderInfo.class,model.getBusiness().getOid(),"D"+ DateUtil.format(model.getInputDate(),"yyyyMM").substring(2)));
        }
        ModelUpdateUtil.saveModel(model,"member.oid","serveUser.oid","payType","otherAmount","accountDate","remark");
        double orderAmount=0d,payAmount,allPayAmount=0d;
        List<String> pt=new ArrayList<>();
        ModelUpdateUtil.delete(OrderPay.class,QueryCondition.eq("order.oid",model.getOid()));
        for(OrderPay pay : pays){
            pay.setOid(null);
            pay.setOrder(model);
            if(pay.getPayAmount()>0) {
                ModelUpdateUtil.saveModel(pay);
                allPayAmount += pay.getPayAmount();
                pt.add(pay.getPayType());
            }
        }
        model.setPayType(pt.toArray(new String[]{}));
        ModelUpdateUtil.delete(OrderDetail.class,QueryCondition.eq("order.oid",model.getOid()));
        for(OrderDetail detail : list){
            detail.setOid(null);
            detail.setOrder(model);
            detail.setServe(ModelQueryList.getModel(detail.getServe(),"*"));
            detail.setPrice(detail.getServe().getPrice());
            detail.setDiscount(null==detail.getServe().getDiscount()?0:detail.getServe().getDiscount());
            detail.setTotal(NumberUtil.round(detail.getPrice()*detail.getNum()*(100-detail.getDiscount())/100.0,2));
            ModelUpdateUtil.saveModel(detail);
            orderAmount+=detail.getTotal();
        }
        model.setOrderAmount(orderAmount);
        model.setPreferentialAmount(NumberUtil.round(orderAmount*model.getMember().getLevel().getDiscount()/100d,2));
        int dayRate=getService(BusinessInfoService.class).getDiscount(model.getInputDate());
        model.setMemberDayAmount(-NumberUtil.round((orderAmount-model.getPreferentialAmount()+model.getOtherAmount())*dayRate/100d,2));
        payAmount=NumberUtil.round(orderAmount-model.getPreferentialAmount()+model.getOtherAmount()+model.getMemberDayAmount(),2);
        model.setPayAmount(payAmount);
        ModelUpdateUtil.updateModel(model,"payType","orderAmount","preferentialAmount","memberDayAmount","payAmount");
        if(NumberUtil.round(payAmount-allPayAmount,2)!=0) throw new MException("实付金额和付款明细不匹配");
        updateOrderAmount(model.getOid());
        return model;
    }
    /**
     * 更新订单金额
     */
    private void updateOrderAmount(String oid) throws Exception {
        DataRow dr= DBManager.queryFirstRow("select ifnull(sum(total),0) total from o_order_detail where order_oid=?",oid);
        OrderInfo model=ModelQueryList.getModel(OrderInfo.class,oid,"*","member.level.discount");
        int dayRate=getService(BusinessInfoService.class).getDiscount(model.getInputDate());
        int levelRate=model.getMember().getLevel().getDiscount();
        model.setOrderAmount(dr.get(Double.class,"total"));
        model.setPreferentialAmount(NumberUtil.round(model.getOrderAmount()*levelRate/100.0,2));
        model.setMemberDayAmount(-NumberUtil.round((model.getOrderAmount()-model.getPreferentialAmount()+model.getOtherAmount())*dayRate/100.0,2));
        model.setPayAmount(NumberUtil.round(model.getOrderAmount()-model.getPreferentialAmount()+model.getOtherAmount()+model.getMemberDayAmount()));
        ModelUpdateUtil.updateModel(model,"orderAmount","preferentialAmount","memberDayAmount","payAmount");
    }

    @Override
    public void deleteOrder(OrderInfo model) throws Exception {
        ModelCheckUtil.equals(model,new String[]{"status","inputUser.oid"},new Object[]{OrderModel.StatusSave,PowerUtil.getUser().getOid()},"状态错误");
        ModelUpdateUtil.deleteModel(model);
        ModelUpdateUtil.delete(OrderDetail.class,QueryCondition.eq("order.oid",model.getOid()));
    }

    @Override
    public void submitAfter(OrderInfo model) throws Exception {
        model= ModelQueryList.getModel(model,"*");
        pays=ModelQueryList.getModelList(OrderPay.class,new String[]{"*"},null,QueryCondition.eq("order.oid",model.getOid()));
        for(OrderPay pay : pays) {
            if (OrderInfo.PayTypeBalance.equals(pay.getPayType())) {
                //充值核算 并更新订单上的数据
                Double[] amounts = getService(RechargeOffsetService.class).create(model.getOid(),pay.getPayAmount());
                pay.setPayRealMoney(amounts[0]);
                pay.setPayGiveMoney(amounts[1]);
            } else {
                pay.setPayRealMoney(pay.getPayAmount());
                pay.setPayGiveMoney(0d);
            }
            ModelUpdateUtil.updateModel(pay, "payRealMoney", "payGiveMoney");
        }
        //清除首页统计缓存 订单
        RuntimeData.getService(PageService.class).clearOrder(model.getInputStore().getOid());
    }

    @Override
    public void backAfter(OrderInfo model) throws Exception {
        model= ModelQueryList.getModel(model,"*");
        pays=ModelQueryList.getModelList(OrderPay.class,new String[]{"*"},null,QueryCondition.eq("order.oid",model.getOid()));
        for(OrderPay pay : pays) {
            if (OrderInfo.PayTypeBalance.equals(pay.getPayType())) {
                //充值核算删除 并更新订单上的数据
                getService(RechargeOffsetService.class).remove(model.getOid(),pay.getPayAmount());
            }
            pay.setPayRealMoney(null);
            pay.setPayGiveMoney(null);
            ModelUpdateUtil.updateModel(pay, "payRealMoney", "payGiveMoney");
        }
        //清除首页统计缓存
        RuntimeData.getService(PageService.class).clearOrder(model.getInputStore().getOid());
    }

    @Override
    public void confirmOrder() throws Exception {
        String remark=model.getRemark();
        Date accountDate=model.getAccountDate();
        if(null==accountDate) throw new MException("请选择账期");
        model= ModelQueryList.getModel(model,"*");
        if(!OrderModel.StatusConfirm.equals(model.getStatus())) throw new MException("状态错误");
        model.setConfirmUser(PowerUtil.getUser());
        model.setConfirmDate(new Date());
        model.setStatus(OrderModel.StatusDone);
        model.setAccountDate(accountDate);
        model.setRemark(remark);
        ModelUpdateUtil.updateModel(model,"confirmUser.oid","confirmDate","status","accountDate","remark");
        //添加金额记录
        MoneyRecordUtil.addOrder(model);
        //更新订单汇总
        OrderCollectUtil.add(model.getInputStore().getOid(),model.getAccountDate());
        OrderCollectUtil.start();
        //清除首页统计缓存
        RuntimeData.getService(PageService.class).clearOrder(model.getInputStore().getOid());
    }

    @Override
    public OrderInfo getModel() {
        return model;
    }

    public void setModel(OrderInfo model) {
        this.model = model;
    }

    public List<OrderDetail> getList() {
        return list;
    }

    public void setList(List<OrderDetail> list) {
        this.list = list;
    }

    public List<OrderPay> getPays() {
        return pays;
    }

    public void setPays(List<OrderPay> pays) {
        this.pays = pays;
    }
}
